package com.CampaignManager.client;

import java.util.List;

import com.CampaignManager.shared.CityDTO;
import com.CampaignManager.shared.PlayerDTO;
import com.CampaignManager.shared.ResourceAmountDTO;
import com.CampaignManager.shared.UnitDTO;
import com.CampaignManager.shared.UnitTypeDTO;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;

public class BuyUnitsForm extends Composite {

	private static BuyUnitsFormUiBinder uiBinder = GWT.create(BuyUnitsFormUiBinder.class);
	interface BuyUnitsFormUiBinder extends UiBinder<Widget, BuyUnitsForm> {}
	
	private CampaignManager mainForm = null;
	private CityDTO city = null;
	private PlayerDTO playerInfo = null;
	
	private String modelType = "blank";

	public BuyUnitsForm(CityDTO city, CampaignManager mainForm, PlayerDTO playerInfo) {
		
		this.mainForm = mainForm;
		this.city = city;
		this.playerInfo = playerInfo;
		
		initWidget(uiBinder.createAndBindUi(this));
		
		loadUnitTypeData();
		resourceForm.RefreshTable(playerInfo);
	}
	
	@UiField
	Label lblFactionHeading;
	@UiField
	Label lblFactionDetail;
	@UiField
	FlexTable factionTable;	
	@UiField
	FlexTable mercTable;
		
	@UiField
	ResourceForm resourceForm;
	
	private void loadUnitTypeData() {
		if (playerInfo.getFaction().equals(city.getFaction())) {
			this.lblFactionHeading.setVisible(true);
			this.lblFactionDetail.setVisible(true);
			SetupTable(factionTable);
			mainForm.campaignService.GetUnitTypes(city.getFaction(), false, new AsyncCallback<UnitTypeDTO[]>() {
				public void onFailure(Throwable error) {
					mainForm.handleError(error);
				}
				public void onSuccess(UnitTypeDTO[] unitTypes) {
					for (UnitTypeDTO u : unitTypes) {
						DisplayUnitTypeRow(factionTable, u);
					}
				}
			});
		}
		
		if (!playerInfo.getFaction().equals(city.getFaction()) ||
			 playerInfo.getFaction().equals("Khador") ||
			 playerInfo.getFaction().equals("Cygnar")) {
			SetupTable(mercTable);
			mainForm.campaignService.GetUnitTypes(city.getFaction(), true, new AsyncCallback<UnitTypeDTO[]>() {
				public void onFailure(Throwable error) {
					mainForm.handleError(error);
				}
				public void onSuccess(UnitTypeDTO[] unitTypes) {
					for (UnitTypeDTO u : unitTypes) {
						DisplayUnitTypeRow(mercTable, u);
					}
				}
			});
		}
		
	}
	private void SetupTable(FlexTable table) {

		table.getCellFormatter().setWidth(0, 0, "50");
		
		table.setText(0, 1, "Name");
		table.setText(0, 3, "Field Allowance");
		table.setText(0, 4, "Point Value");
		table.setText(0, 7, "Cost");
		
		table.getRowFormatter().addStyleName(0, "watchListHeader");
		table.addStyleName("watchList");
		table.getCellFormatter().addStyleName(0, 3, "watchListNumericColumn");
		table.getCellFormatter().addStyleName(0, 4, "watchListNumericColumn");
	}
	
	public void DisplayUnitTypeRow(FlexTable table, UnitTypeDTO unitType) {
		final int row = table.getRowCount();
		if (!unitType.getModelType().equals(modelType)) {
			modelType = unitType.getModelType();
			table.setText(row, 0, unitType.getModelType().toString());
			table.getRowFormatter().addStyleName(row, "watchListHeader");
			DisplayUnitTypeRow(table, unitType, row+1);
		} else {
			DisplayUnitTypeRow(table, unitType, row);
		}		
	}
	public void DisplayUnitTypeRow(FlexTable table, final UnitTypeDTO unitType, final int row) {
		
		final List<ResourceAmountDTO> cost = unitType.getPurchaseCost(playerInfo.getFaction());
		boolean isMerc = unitType.isMerc(playerInfo.getFaction());
		
		String buttonText = "Conscript";
		if (isMerc) buttonText = "Hire";
		
		final Button buy = new Button(buttonText);
		buy.addClickHandler(new ClickHandler() {			
			@Override
			public void onClick(ClickEvent event) {
				if (!unitType.getAttached().isEmpty()) {
					String warning = unitType.getName()+" has to be attached to a "+unitType.getAttached()+", are you sure you want to hire 'em?";
					if (!Window.confirm(warning)) return;
				} else {
					String warning = "Are you sure you want to hire "+unitType.getName();
					if (!Window.confirm(warning)) return;
				}
				
				buy.setText("Please wait...");
				buy.setEnabled(false);
																
				mainForm.campaignService.BuyUnit(unitType, new AsyncCallback<UnitDTO>() {			
					public void onFailure(Throwable error) {
						mainForm.handleError(error);
					}
					public void onSuccess(UnitDTO unit) {
						if (unit == null) {
							Window.alert("Unable to buy that unit, you'll have to refresh the page");					
						} else {
							for (ResourceAmountDTO rac : cost) {
								ResourceAmountDTO pr = playerInfo.getResource(rac.getResource());
								pr.setAmount(pr.getAmount()-rac.getAmount());				
							}
							resourceForm.RefreshTable(playerInfo);
							playerInfo.getUnits().add(unit);
							mainForm.showUnits();
						}
					}
				});
			}
		});
		
		Long pointLimit = PlayerDTO.getPointLimit(playerInfo.getLevel());
		if ((playerInfo.getArmySize() + unitType.getMinPoints()) > pointLimit) {
			buy.setEnabled(false);
			buy.setTitle("Army Size limit: "+pointLimit);
		}
		if (!playerInfo.canPlayerAffordThis(cost)) {
			buy.setEnabled(false);
			buy.setTitle("Can't Afford");			
		}
		
		table.setWidget(row, 0, buy);
		
		Anchor nameLink = new Anchor(unitType.getName());
		nameLink.setHref("http://battlecollege.wikispaces.com/" + unitType.getHref());
		nameLink.setTarget("_blank");
		table.setWidget(row, 1, nameLink);
		
		table.setText(row, 3, unitType.getFieldAllowance().toString());
		table.getCellFormatter().addStyleName(row, 3, "watchListNumericColumn");
		if (unitType.getMaxPoints() > 0) {
			table.setText(row, 4, unitType.getMinPoints().toString() + " or " + unitType.getMaxPoints().toString());
		}
		else {
			table.setText(row, 4, unitType.getMinPoints().toString());
		}
		table.getCellFormatter().addStyleName(row, 4, "watchListNumericColumn");
				
		table.setText(row, 7, mainForm.CostText(cost));
		
		/*if (playerInfo.isAdmin()) {
			HorizontalPanel h = new HorizontalPanel();
			for (final String resource : RegionClient.getAllResources()) {
				Button change = new Button(resource);
				change.addClickHandler(new ClickHandler() {			
					@Override
					public void onClick(ClickEvent event) {
						mainForm.campaignService.UpdateCost(unitType.getId(), resource, new AsyncCallback<Void>() {
							public void onFailure(Throwable error) {
								mainForm.handleError(error);
							}
							public void onSuccess(Void ignore) {
								ResourceAmountClient theResource = null;
								for (ResourceAmountClient rac : unitType.getResources()) {
									if (rac.getResource().equalsIgnoreCase(resource)) {
										theResource = rac;
									}
								}
								if (theResource == null) {
									//didn't find it, create it
									theResource = new ResourceAmountClient();
									theResource.setResource(resource);
									theResource.setAmount(0L);
									
									List<ResourceAmountClient> racs = new ArrayList<ResourceAmountClient>();
									for (ResourceAmountClient r : unitType.getResources()) {
										racs.add(r);
									}									
									racs.add(theResource);
									unitType.setResources(racs.toArray(new ResourceAmountClient[0]));
								}
								theResource.setAmount(theResource.getAmount()+1L);
								
								DisplayUnitTypeRow(unitType, row);
							}
						});
					}
				});
				h.add(change);
			}
			unitTypeTable.setWidget(row, 6, h);
		}*/
	}
}
